package com.A21MobileSales;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import android.content.Context;
import android.text.TextUtils;

import com.A21.Object.A21CustomerPrice;
import com.A21.Object.A21OPPriceBookDetail;
import com.A21.Object.A21OrderHeader;
import com.A21.Object.Global;
import com.A21.Object.MSTCustomer;
import com.A21.Object.MSTGroupPriceTable;
import com.A21.Object.MSTMultiTierDiscountOP;
import com.A21.Object.MSTPriceBracket;
import com.A21.Object.MSTPriceTable;
import com.A21.Object.MSTProduct;
import com.A21.Object.MSTSettings;
import com.A21.Object.SMGSTType;
import com.A21.Object.SMUnitConversion;
import com.A21.Object.SMUnitConversionProd;
import com.A21.Object.TrnDetail;
import com.A21MobileSales.DataBase.DatabaseHelper;

public class Common {

	private DatabaseHelper objDBHelper;

	public Common(Context _Context) {
		objDBHelper = new DatabaseHelper(_Context);
	}

	public MSTSettings GetSystemSetting() {
		MSTSettings row = objDBHelper.GetSystemSettingsById("1");
		return row;
	}

	public MSTProduct GetProduct(String Product) throws Exception {
		MSTProduct row = objDBHelper.GetProductByCode(Product);
		return row;
	}

	public MSTCustomer GetCustomer(String Code) throws Exception {
		MSTCustomer row = objDBHelper.GetCustomerByCode(Code);
		return row;
	}

	public MSTPriceTable GetPriceTable(String Code, String Product,
			String Currency, String ProductSubCode, String UOM)
			throws Exception {
		MSTPriceTable row = objDBHelper
				.GetPriceTableByCodeProductCurrencyProductsubCodeUOM(Code,
						Product, Currency, ProductSubCode, UOM);
		return row;
	}

	public MSTGroupPriceTable GetGroupPriceTable(String Code, String Group,
			String Currency) throws Exception {
		MSTGroupPriceTable row = objDBHelper
				.GetGroupPriceTableByCodeGroupCurrency(Code, Group, Currency);
		return row;
	}

	public A21OPPriceBookDetail GetPriceBookPrice(int PriceBookID,
			String Product, String UOM, String Currency) throws Exception {
		A21OPPriceBookDetail row = objDBHelper
				.GetPriceBookDetailByPriceBookIDProductUOMCurrency(
						String.valueOf(PriceBookID), Product, UOM, Currency);
		return row;
	}

	public MSTPriceBracket GetPriceBracket(String Code, String Product)
			throws Exception {
		MSTPriceBracket row = objDBHelper.GetPriceBracketByCodeProduct(Code,
				Product);
		return row;
	}

	public static boolean isNullOrEmpty(String s) {
		return s == null || s.length() == 0;
	}

	public TrnDetail GetConversionFactor(TrnDetail det) throws Exception {
		MSTProduct Product = GetProduct(det.Product);
		if (!det.StockUnit.equals(det.UOM)) {
			if (isNullOrEmpty(Product.ConvProd)) {
				SMUnitConversion uc = objDBHelper.GetSMUnitConversion(det.UOM,
						det.StockUnit);
				if (uc != null) {
					det.Conversion = uc.ConversionFactor;
				} else {
					throw new Exception("Unit Conversion Table not entered");
				}
			} else {
				if (Product.ConvProd.equals("0")) {
					SMUnitConversion uc = objDBHelper.GetSMUnitConversion(
							det.UOM, det.StockUnit);
					if (uc != null) {
						det.Conversion = uc.ConversionFactor;
					} else {
						throw new Exception("Unit Conversion Table not entered");
					}
				} else {
					SMUnitConversionProd uc = objDBHelper
							.GetConversionByProductByProductCodeToUnit(
									det.Product, det.UOM, det.StockUnit);
					if (uc != null) {
						det.Conversion = uc.ConversionFactor;
					} else {
						throw new Exception("Unit Conversion Table not entered");
					}
				}
			}
		}
		return det;
	}

	private enum CustomerPriceType {
		T, A, G, B, O, L, P, D, R, F, E, M, C,S;
	}

	public A21CustomerPrice GetA21CustomerPrice(String Code, String Product)
			throws Exception {
		MSTCustomer Customer = GetCustomer(Code);
		A21CustomerPrice row = new A21CustomerPrice();
		TrnDetail det = new TrnDetail();
		det.Product = Product;
		det = GetProductPrice(Code, det);
		row.Currency = Customer.Currency;
		DecimalFormat df2 = new DecimalFormat("#0.00");
		row.UPrice = df2.format(det.UnitPrice);
		row.PType = GetCustomerProductPriceType(Code, Product);
		CustomerPriceType priceType = CustomerPriceType
				.valueOf(Customer.CusType);
		return row;
	}

	public String GetCustomerProductPriceType(String _Code, String _Product)
			throws Exception {
		MSTCustomer Customer = GetCustomer(_Code);
		CustomerPriceType priceType = CustomerPriceType
				.valueOf(Customer.CusType);
		switch (priceType) {
		case T:
			return "Price Table(sales)";
		case A:
			return "Price Table(Last)";
		case G:
			return "Group Table(sales)";
		case B:
			return "Group Table(Last)";
		case O:
			return GetProductPriceType(_Product, "O");
		case L:
			return "List Price";
		case P:
			return "Sales Promotion";
		case D:
			return "Dealer";
		case R:
			return "Retail";
		case F:
			return "Price Book";
		case E:
			return "Last Price";
		case M:
			return "Bracket Price";
		case C:
			return "Multi-tier Trade Discount";
		default:
			return "";
		}
	}

	public String GetProductPriceType(String _Product, String _PriceType)
			throws Exception {
		MSTProduct Product = GetProduct(_Product);
		if (_PriceType.equals("")) {
			_PriceType = Product.PriceType;
		}
		ProductPriceType priceType = ProductPriceType.valueOf(_PriceType);
		switch (priceType) {
		case L:
			return "List Price";
		case R:
			return "Retail Price";
		case D:
			return "Dealer Price";
		case P:
			return "Promotion Price";
		case A:
			return "Last Selling Price";
		case M:
			return "Minimum Price";
		default:
			return "";
		}
	}

	/*
	 * Dim rsMTD As DAO.Recordset Set rsMTD =
	 * currentDB.OpenRecordset("SELECT * FROM MSTMultiTierDiscountOP WHERE Code='"
	 * & Customer & "' AND Product='" & Product & "' AND Currency='" &
	 * Screen.ActiveForm!Currency & "' AND UOM='" & cn(TP!SalesUnit, "") & "'",
	 * dbOpenForwardOnly, dbReadOnly) If Not rsMTD.EOF Then
	 * 
	 * CustGSTType = Nz(DLookup("GSTType", "MSTCustomerSupplier", "Code='" &
	 * Customer & "'"), "") CustGST = Nz(DLookup("GST", "SMGSTType", "Code='" &
	 * CustGSTType & "'"), 0)
	 * 
	 * If cn(rsMTD!L3DateFrom, "") <= Screen.ActiveForm!TrnDate And
	 * cn(rsMTD!L3DateTo, "") >= Screen.ActiveForm!TrnDate Then
	 * 
	 * If Screen.ActiveForm!GSTInc = 0 Then UnitPrice =
	 * cn(rsMTD!L3MarkDownPrice, 0) Else UnitPrice = cn(rsMTD!L3MarkDownPrice,
	 * 0) + (cn(rsMTD!L3MarkDownPrice, 0) * CustGST) End If
	 * 
	 * LineDiscount1 = cn(rsMTD!L3TDiscPercent, 0)
	 * 
	 * ElseIf cn(rsMTD!L2DateFrom, "") <= Screen.ActiveForm!TrnDate And
	 * cn(rsMTD!L2DateTo, "") >= Screen.ActiveForm!TrnDate Then
	 * 
	 * L2PromotionPrice = cn(rsMTD!L1NormalPrice, 0) * (1 -
	 * cn(rsMTD!L2DiscPercent, 0))
	 * 
	 * If Screen.ActiveForm!GSTInc = 0 Then UnitPrice = L2PromotionPrice Else
	 * UnitPrice = L2PromotionPrice + (L2PromotionPrice * CustGST) End If
	 * 
	 * LineDiscount1 = cn(rsMTD!L2TDiscPercent, 0)
	 * 
	 * ElseIf cn(rsMTD!L1DateFrom, "") <= Screen.ActiveForm!TrnDate And
	 * cn(rsMTD!L1DateTo, "") >= Screen.ActiveForm!TrnDate Then
	 * 
	 * If Screen.ActiveForm!GSTInc = 0 Then UnitPrice = cn(rsMTD!L1NormalPrice,
	 * 0) Else UnitPrice = cn(rsMTD!L1NormalPrice, 0) + (cn(rsMTD!L1NormalPrice,
	 * 0) * CustGST) End If
	 * 
	 * LineDiscount1 = cn(rsMTD!L1TDiscPercent, 0)
	 * 
	 * End If
	 * 
	 * ExchRate = 1
	 * 
	 * End If rsMTD.Close Set rsMTD = Nothing
	 */

	public TrnDetail GetProductPrice(String _Code, TrnDetail det)
			throws Exception {
		MSTProduct Product = GetProduct(det.Product);
		MSTCustomer Customer = GetCustomer(_Code);
		MSTSettings Setting = GetSystemSetting();
		CustomerPriceType priceType = CustomerPriceType
				.valueOf(Customer.CusType);
		switch (priceType) {
		case T:
			det.UnitPrice = PriceTableSellingPrice(_Code, det.Product,
					Customer.Currency, "", Product.SalesUnit);
			break;
		case A:
			det.UnitPrice = PriceTableLastSellPrice(_Code, det.Product,
					Customer.Currency, "", Product.SalesUnit);
			break;
		case G:
			det.UnitPrice = GroupPriceTableSellingPrice(_Code, Product.Class1,
					Customer.Currency);
			break;
		case B:
			det.UnitPrice = GroupPriceTableLastSellingPrice(_Code,
					Product.Class1, Customer.Currency);
			break;
		case O:
			det.UnitPrice = ProductPrice(det.Product, "_");
			break;
		case L:
			det.UnitPrice = ProductPrice(det.Product, "L");
			break;
		case P:
			det.UnitPrice = ProductPrice(det.Product, "P");
			break;
		case D:
			det.UnitPrice = ProductPrice(det.Product, "D");
			break;
		case R:
			det.UnitPrice = ProductPrice(det.Product, "R");
			break;
		case F:
			double[] val = PriceBookPrice(Customer.PriceBookID, det.Product,
					Product.SalesUnit, Customer.Currency);
			det.UnitPrice = val[0];
			det.LineDiscount1 = val[1];
			break;
		case E:
			det.UnitPrice = ProductPrice(det.Product, "A");
			break;
		case M:
			det = PriceBracketPrice(_Code, det);
			break;
		case C:
			det = MultiTierTradeProduct(Customer, det);
			break;
		default:
			det.UnitPrice = 0;
			break;
		}
		return det;
	}

	public TrnDetail MultiTierTradeProduct(MSTCustomer Customer, TrnDetail det)
			throws Exception {
		MSTMultiTierDiscountOP row = objDBHelper.GetCustomerMultiTierProduct(
				Customer.Code, det.Product, det.UOM, Customer.Currency);
		if (row != null) {

			final SimpleDateFormat df = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			String CustGSTType = Customer.GSTType;
			SMGSTType rowGST = objDBHelper.GetGSTByCode(CustGSTType);
			double CustGST = rowGST == null ? 0 : rowGST.GST;
			A21OrderHeader Header = Global.getA21OrderHeader();
			Date TrnDate, L3DateFrom, L3DateTo, L2DateFrom, L2DateTo, L1DateFrom, L1DateTo;
			TrnDate= L3DateFrom= L3DateTo= L2DateFrom= L2DateTo= L1DateFrom= L1DateTo=null;
			if (!isNullOrEmpty(Header.TrnDate)) {
				TrnDate = df.parse(Header.TrnDate);
			}
			if (!isNullOrEmpty(row.L3DateFrom)) {
				L3DateFrom = df.parse(row.L3DateFrom);
			}
			if (!isNullOrEmpty(row.L3DateTo)) {
				L3DateTo = df.parse(row.L3DateTo);
			}
			if (!isNullOrEmpty(row.L2DateFrom)) {
				L2DateFrom = df.parse(row.L2DateFrom);
			}
			if (!isNullOrEmpty(row.L2DateTo)) {
				L2DateTo = df.parse(row.L2DateTo);
			}
			if (!isNullOrEmpty(row.L1DateFrom)) {
				L1DateFrom = df.parse(row.L1DateFrom);
			}
			if (!isNullOrEmpty(row.L1DateTo)) {
				L1DateTo = df.parse(row.L1DateTo);
			}
			if (L3DateFrom!=null && L3DateFrom.compareTo(TrnDate) <= 0
					&& L3DateTo.compareTo(TrnDate) >= 0) {

				if (!Customer.GSTInc) {
					det.UnitPrice = row.L3MarkDownPrice;
				} else {
					det.UnitPrice = row.L3MarkDownPrice
							+ (row.L3MarkDownPrice * CustGST);

				}
				det.LineDiscount1 = row.L3TDiscPercent;
			} else if (L2DateFrom!=null && L2DateFrom.compareTo(TrnDate) <= 0
					&& L2DateTo.compareTo(TrnDate) >= 0) {

				double L2PromotionPrice = row.L1NormalPrice
						* (1 - row.L2DiscPercent);
				if (!Customer.GSTInc) {
					det.UnitPrice = L2PromotionPrice;
				} else {
					det.UnitPrice = L2PromotionPrice
							+ (L2PromotionPrice * CustGST);

				}
				det.LineDiscount1 = row.L2TDiscPercent;
			} else if (L1DateFrom!=null && L1DateFrom.compareTo(TrnDate) <= 0
					&& L1DateTo.compareTo(TrnDate) >= 0) {

				if (!Customer.GSTInc) {
					det.UnitPrice = row.L1NormalPrice;
				} else {
					det.UnitPrice = row.L1NormalPrice
							+ (row.L1NormalPrice * CustGST);

				}
				det.LineDiscount1 = row.L1TDiscPercent;
			}

			// ExchRate = 1

		}else{ 
			det.UnitPrice = ProductPrice(det.Product, "_");
		}
		return det;
	}

	public TrnDetail PriceBracketPrice(String Code, TrnDetail det) throws Exception {

		if (det.OrderQuantity == 0) {
			det.UnitPrice = 0;
			return det;
		}
		MSTPriceBracket row = null;
		try {
			row = GetPriceBracket(Code, det.Product);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (row != null) {
			if (det.OrderQuantity > 0 && det.OrderQuantity <= row.Bracket1) {
				det.UnitPrice = row.Bracket1_Price;
				det.UOM = row.UOM1;
			} else {
				det.UnitPrice = row.Bracket1_Price;
				det.UOM = row.UOM1;
				if (det.OrderQuantity > row.Bracket1
						&& det.OrderQuantity <= row.Bracket2) {
					det.UnitPrice = row.Bracket2_Price;
					det.UOM = row.UOM2;
				} else {
					det.UnitPrice = row.Bracket2_Price == 0 ? det.UnitPrice
							: row.Bracket2_Price;
					det.UOM = row.UOM2 == null ? det.UOM : row.UOM2;
					if (det.OrderQuantity > row.Bracket2
							&& det.OrderQuantity <= row.Bracket3) {
						det.UnitPrice = row.Bracket3_Price;
						det.UOM = row.UOM3;
					} else {
						det.UnitPrice = row.Bracket3_Price == 0 ? det.UnitPrice
								: row.Bracket3_Price;
						det.UOM = row.UOM3 == null ? det.UOM : row.UOM3;
						if (det.OrderQuantity > row.Bracket3
								&& det.OrderQuantity <= row.Bracket4) {
							det.UnitPrice = row.Bracket4_Price;
							det.UOM = row.UOM4;
						} else {
							det.UnitPrice = row.Bracket4_Price == 0 ? det.UnitPrice
									: row.Bracket4_Price;
							det.UOM = row.UOM4 == null ? det.UOM : row.UOM4;
							if (det.OrderQuantity > row.Bracket4
									&& det.OrderQuantity <= row.Bracket5) {
								det.UnitPrice = row.Bracket5_Price;
								det.UOM = row.UOM5;
							}
						}
					}
				}
			}

		}else{ 
			det.UnitPrice = ProductPrice(det.Product, "_");
		}
		return det;
	}

	public double PriceTableSellingPrice(String Code, String Product,
			String Currency, String ProductSubCode, String UOM) throws Exception {
		double retval = 0;
		MSTPriceTable row = null;
		try {
			row = GetPriceTable(Code, Product, Currency, ProductSubCode, UOM);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (row != null) {
			retval = row.SellingPrice;
		}else{ 
			retval = ProductPrice(Product, "_");
		}
		return retval;
	}

	public double PriceTableLastSellPrice(String Code, String Product,
			String Currency, String ProductSubCode, String UOM) throws Exception {
		double retval = 0;
		MSTPriceTable row = null;
		try {
			row = GetPriceTable(Code, Product, Currency, ProductSubCode, UOM);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (row != null) {
			retval = row.LastSellPrice;
		}else{ 
			retval = ProductPrice(Product, "_");
		}
		return retval;
	}

	public double GroupPriceTableSellingPrice(String Code, String Group,
			String Currency) {
		double retval = 0;
		MSTGroupPriceTable row = null;
		try {
			row = GetGroupPriceTable(Code, Group, Currency);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (row != null) {
			retval = row.SellingPrice;
		}
		return retval;
	}

	public double GroupPriceTableLastSellingPrice(String Code, String Group,
			String Currency) {
		double retval = 0;
		MSTGroupPriceTable row = null;
		try {
			row = GetGroupPriceTable(Code, Group, Currency);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (row != null) {
			retval = row.LastSellPrice;
		}
		return retval;
	}

	private enum ProductPriceType {
		L, R, D, P, A, M,S,_;
	}

	public double ProductPrice(String _Product, String _PriceType)
			throws Exception {
		double retval = 0;
		MSTProduct Product = GetProduct(_Product);
		if (_PriceType.equals("")) {
			if( Product.PriceType!=null){
			_PriceType = Product.PriceType;
			}
		}
		ProductPriceType priceType = ProductPriceType.valueOf(_PriceType);
		switch (priceType) {
		case L:
			retval = Product.ListPrice;
			break;
		case R:
			retval = Product.RetailPrice;
			break;
		case D:
			retval = Product.DealerPrice;
			break;
		case P:
			retval = Product.PromotionPrice;
			break;
		case A:
			retval = Product.LastSellPrice;
			break;
		case M:
			retval = Product.MinimumPrice;
			break;
		default:
			retval = Product.ListPrice;
			break;
		}
		return retval;
	}

	public double[] PriceBookPrice(int PriceBookID, String Product, String UOM,
			String Currency) {
		double retval[] = new double[] { 0, 0 };
		if (PriceBookID != 0) {
			A21OPPriceBookDetail row = null;
			try {
				row = GetPriceBookPrice(PriceBookID, Product, UOM, Currency);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (row != null) {
				retval[0] = row.SellingPrice;
				retval[1] = row.LineDiscount1;
			}
		} else {
			try {
				retval[0] = ProductPrice(Product, "");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return retval;
	}

}
